﻿#include "asycipc/handshake.hpp"

#include <chrono>
#include <random>
#include <sstream>

namespace asycipc {
namespace {
std::string GenerateToken(uint64_t counter) {
  std::ostringstream oss;
  oss << "resume-" << counter;
  return oss.str();
}

std::string GenerateSessionId(uint64_t counter) {
  std::ostringstream oss;
  oss << "session-" << counter;
  return oss.str();
}
}  // namespace

HandshakeManager::HandshakeManager(HandshakeConfig config)
    : config_(std::move(config)) {}

HandshakeResponse HandshakeManager::Negotiate(const HandshakeRequest& request,
                                              SessionContext& session) {
  if (request.protocol_version != config_.protocol_version) {
    throw HandshakeError("protocol version mismatch");
  }
  if (!config_.allowed_app_ids.empty() &&
      !config_.allowed_app_ids.count(request.app_id)) {
    throw HandshakeError("app id not allowed");
  }

  ++session_counter_;
  const uint64_t initial_seq = 1;
  const std::string session_id = GenerateSessionId(session_counter_);
  const std::string token = GenerateToken(session_counter_);

  session.SetSessionId(session_id);
  session.TransitionTo(SessionState::kNegotiating);
  session.TransitionTo(SessionState::kActive);

  HandshakeResponse response;
  response.session_id = session_id;
  response.initial_seq = initial_seq;
  response.resume_token = token;
  return response;
}

}  // namespace asycipc
